package com.cc.dy.http.impl;

import cn.hutool.core.collection.CollUtil;
import com.cc.dy.api.response.DyResponse;
import com.cc.dy.executer.DyService;
import com.cc.dy.http.AbstractDyHttpClient;
import com.cc.dy.json.JsonSerializer;
import com.cc.dy.json.impl.FastJsonSerializer;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author chenChao 2023-09-08 9:51
 */
@Slf4j
public class ApacheDyHttpClient extends AbstractDyHttpClient {
    CloseableHttpClient httpClient = HttpClients.createDefault();

    public ApacheDyHttpClient(DyService dyService) {
        super(dyService, new FastJsonSerializer());
    }

    public ApacheDyHttpClient(DyService dyService, JsonSerializer jsonSerializer) {
        super(dyService, jsonSerializer);
    }


    /**
     * GET请求
     *
     * @param url     请求地址
     * @param headers 请求头
     * @param t       返回对象的类型
     * @return {@link T}
     */
    @Override
    public <T extends DyResponse> T getWithHeaders(String url, Map<String, String> headers, Class<T> t) {
        ClassicHttpRequest request = new BasicClassicHttpRequest("GET", url);
        if (CollUtil.isNotEmpty(headers)) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                request.addHeader(entry.getKey(), entry.getValue());
            }
        }
        BasicHttpClientResponseHandler basicHttpClientResponseHandler = new BasicHttpClientResponseHandler();
        try {
            log.info("GET请求，地址：{}，请求头：{}", url, headers);
            String response = httpClient.execute(request, basicHttpClientResponseHandler);
            log.info("GET响应，地址：{}，请求头：{}，结果：{}", url, headers, response);
            return this.getJsonSerializer().parseResponse(response, t);
        } catch (IOException e) {
            log.error("GET请求异常:", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * POST请求
     *
     * @param url        请求接口地址
     * @param headers    请求头
     * @param urlRequest 请求地址参数
     * @param request    请求对象
     * @param t          类型
     * @return {@link T}
     */
    @Override
    public <T extends DyResponse> T postWithHeaders(String url, Map<String, String> headers, Map<String, Object> urlRequest, Object request, Class<T> t) {
        if (CollUtil.isNotEmpty(urlRequest)) {
            url = urlJoinParams(url, urlRequest);
        }
        HttpPost post = new HttpPost(url);
        RequestConfig config = RequestConfig.custom()
                .setConnectionRequestTimeout(dyService.getDyConfig().getHttpConnectionTimeout(), TimeUnit.SECONDS)
                .setResponseTimeout(dyService.getDyConfig().getHttpTimeout(), TimeUnit.SECONDS)
                .build();
        post.setConfig(config);

        if (CollUtil.isNotEmpty(headers)) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                post.addHeader(entry.getKey(), entry.getValue());
            }
        }

        if (Objects.nonNull(request)) {
            HttpEntity httpEntity = new StringEntity(getJsonSerializer().toJson(request), ContentType.create("application/json", "utf-8"));
            post.setEntity(httpEntity);
        }
        BasicHttpClientResponseHandler basicHttpClientResponseHandler = new BasicHttpClientResponseHandler();
        try {
            log.info("POST请求，地址：{}，请求头：{}, 参数：{}", url, headers, request);
            String response = httpClient.execute(post, basicHttpClientResponseHandler);
            log.info("POST响应，地址：{}，请求头：{}，参数：{}，结果：{}", url, headers, request, response);
            return this.getJsonSerializer().parseResponse(response, t);
        } catch (IOException e) {
            log.error("POST请求异常:", e);
            throw new RuntimeException(e);
        }
    }
}
